package cn.easier.activity.console.controller;

import cn.easier.activity.console.configration.ActivityConsoleConfiguration;
import cn.easier.activity.console.service.ActivityInfoService;
import cn.easier.activity.console.service.ActivityPrizeClawService;
import cn.easier.activity.console.service.ActivityTemplateInfoService;
import cn.easier.activity.console.utils.FileUtil;
import cn.easier.activity.web.entity.ActivityInfo;
import cn.easier.activity.web.entity.ActivityTemplateInfo;
import cn.easier.activity.web.entity.PrizeClawImageMessage;
import cn.easier.club.base.dto.ResultInfo;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;

/**
 * 模板信息Controller(每一个接口都要验证用户，并且执行每个方法都要 where user，隔离用户信息)
 */
@Controller
@RequestMapping("/activity/info")
public class ActivityInfoController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(ActivityInfoController.class);

    /**
     * 前台活动展示链接示例
     */
    @Value("${metadata.configuration.foreground-static-link}")
    public String foregroundStaticLink;

    @Value("${metadata.configuration.bargain-static-link}")
    public String barGainStaticLink;

    @Autowired
    ActivityInfoService activityInfoService;

    @Autowired
    ActivityTemplateInfoService activityTemplateInfoService;

    @Autowired
    ActivityPrizeClawService activityPrizeClawService;

    @Autowired
    private ActivityConsoleConfiguration activityConsoleConfiguration;

    /**
     * 查找所有活动
     *
     * @return
     */
    @GetMapping
    @ResponseBody
    public ResultInfo findPage(
            @RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
            @RequestParam(value = "pageNum", required = false, defaultValue = "10") Integer pageNum,
            @RequestParam(value = "name", required = false, defaultValue = "") String name,
            @RequestParam(value = "title", required = false, defaultValue = "") String title,
            @RequestParam(value = "templateInfoId", required = false, defaultValue = "0") Integer templateInfoId) {
        // todo 如果当前用户不存在，返回异常
        ResultInfo resultInfo = null;
        String user = getPrincipal().getUsername();
        String authoritiesStr = getPrincipal().getAuthoritiesStr();
        try {
            if (authoritiesStr.equals("ROLE_USER_SUPERADMIN") || authoritiesStr.equals("ROLE_USER_ADMIN")) {
                logger.info("当前登录用户角色", authoritiesStr);
                resultInfo = activityInfoService.findAllActivity(pageIndex, pageNum, name, title, templateInfoId);
            } else {
                logger.info("当前登录用户角色", authoritiesStr);
                resultInfo = activityInfoService.findPage(user, pageIndex, pageNum, name, title, templateInfoId);
            }
            logger.info("查询结果：=>{}", resultInfo);
        } catch (Exception e) {
            logger.error("模板分页查询失败，=>{}", e);
            resultInfo = new ResultInfo("ERROR", "模板分页查询失败", null);
        }
        return resultInfo;
    }

    /**
     * 查找当前用户所有活动
     *
     * @return
     */
    @GetMapping("/findAll")
    @ResponseBody
    public List<ActivityInfo> findAll() {
        // todo 如果当前用户不存在，返回异常
        String user = getPrincipal().getUsername();
        String authoritiesStr = getPrincipal().getAuthoritiesStr();
        List<ActivityInfo> activityInfoList = new ArrayList<ActivityInfo>();
        if (authoritiesStr.equals("ROLE_USER_SUPERADMIN") || authoritiesStr.equals("ROLE_USER_ADMIN")) {
            logger.info("当前登录用户角色", authoritiesStr);
            activityInfoList = activityInfoService.findNewAll();
        } else {
            logger.info("当前登录用户角色", authoritiesStr);
            activityInfoList = activityInfoService.findAll(user);
        }
        logger.info("获取指定活动信息，num：=>{}", activityInfoList.size());
        return activityInfoList;
    }

    /**
     * 查找当前用户所有活动
     */
    @GetMapping("/findAllName")
    @ResponseBody
    public HashMap<Integer, String> findAllActivityName() {
        // todo 如果当前用户不存在，返回异常
        String user = getPrincipal().getUsername();
        String authoritiesStr = getPrincipal().getAuthoritiesStr();
        List<ActivityInfo> activityInfoList;
        if (authoritiesStr.equals("ROLE_USER_SUPERADMIN") || authoritiesStr.equals("ROLE_USER_ADMIN")) {
            logger.info("当前登录用户角色: {}", authoritiesStr);
            activityInfoList = activityInfoService.findNewAll();
        } else {
            logger.info("当前登录用户角色: {}", authoritiesStr);
            activityInfoList = activityInfoService.findAll(user);
        }
        logger.info("获取指定活动信息，num：=>{}", activityInfoList.size());
        HashMap<Integer, String> map = new HashMap<>();
        for (ActivityInfo activityInfo : activityInfoList) {
            map.put(activityInfo.getId(), activityInfo.getName());
        }
        return map;
    }

    /**
     * 查找指定活动
     *
     * @return
     */
    @GetMapping("/id/{id}")
    @ResponseBody
    public ActivityInfo findOne(@PathVariable Integer id) {
        // todo 如果当前用户不存在，返回异常
        String user = getPrincipal().getUsername();
        String authoritiesStr = getPrincipal().getAuthoritiesStr();
        ActivityInfo activityInfo = getActivityInfo(authoritiesStr, user, id);
        ResultInfo resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "SUCCESS", activityInfo);
        logger.info("获取指定活动信息：=>{}", resultInfo);
        return activityInfo;
    }

    /**
     * 查找抓娃娃活动指定10张图片
     *
     * @return
     */
    @GetMapping("/getImage/{id}")
    @ResponseBody
    public ResultInfo getImage(@PathVariable Integer id) {
        PrizeClawImageMessage prizeClawImageMessage = activityPrizeClawService.findByOne(id);
        if (prizeClawImageMessage == null) {
            logger.error("获取抓娃娃10张图片失败，当前活动ID没有抓娃娃10张图片。activityInfoId:=>{}", id);
            return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "获取抓娃娃10张图片失败", null);
        }
        logger.info("获取抓娃娃10张图片成功：=>{}", prizeClawImageMessage);
        return new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "SUCCESS", prizeClawImageMessage);
    }

    /**
     * 创建活动对象
     *
     * @param activityInfo 模板对象
     * @return
     */
    @PostMapping("/templateId/{templateId}")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ROLE_USER_SUPERADMIN','ROLE_USER_ADMIN','ROLE_USER_SELF')")
    public ResultInfo create(@PathVariable Integer templateId, ActivityInfo activityInfo,
                             @RequestParam(value = "pcSkipImage", required = false) MultipartFile pcSkipImage,
                             @RequestParam(value = "wapSkipImage", required = false) MultipartFile wapSkipImage) {
        // todo 如果当前用户不存在，返回异常
        ResultInfo resultInfo = null;
        String user = getPrincipal().getUsername();
        // 模板
        ActivityTemplateInfo activityTemplateInfo = activityTemplateInfoService.findOne(templateId);
        if (activityTemplateInfo == null) {
            return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动创建失败，找不到对应的模板信息",
                    null);
        }
        try {
            // 处理跳转图片
            JSONObject skipImageJson = new JSONObject();
            if ((StringUtils.isNotBlank(activityInfo.getSkipUrl()) && pcSkipImage == null)
                    || (StringUtils.isNotBlank(activityInfo.getSkipUrl()) && wapSkipImage == null)) {
                return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "请上传跳转图片", null);
            }

            if (pcSkipImage != null && (!Strings.isNullOrEmpty(pcSkipImage.getOriginalFilename()))) {
                String fileName = pcSkipImage.getOriginalFilename();
                // 验证图片文件格式
                boolean imageFormatFlag = FileUtil.imageFormatVerification(fileName);
                if (!imageFormatFlag) {
                    return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
                            "请选择格式为*.jpg、*.gif、*.bmp、*.png、*.jpeg 的图片", fileName);
                }
                skipImageJson.put("pc", uploadFile(pcSkipImage, activityConsoleConfiguration.activitySkipImagePcPath,
                        "skip_image_pc_"));
            }
            if (wapSkipImage != null && (!Strings.isNullOrEmpty(wapSkipImage.getOriginalFilename()))) {
                String fileName = wapSkipImage.getOriginalFilename();
                // 验证图片文件格式
                boolean imageFormatFlag = FileUtil.imageFormatVerification(fileName);
                if (!imageFormatFlag) {
                    return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
                            "请选择格式为*.jpg、*.gif、*.bmp、*.png、*.jpeg 的图片", fileName);
                }
                skipImageJson.put("wap", uploadFile(wapSkipImage, activityConsoleConfiguration.activitySkipImageWapPath,
                        "skip_image_wap_"));
            }
            // 添加跳转图片路径
            if (StringUtils.isNotBlank(activityInfo.getSkipUrl())) {
                activityInfo.setSkipImage(skipImageJson.toJSONString());
            } else {
                activityInfo.setSkipImage(null);
            }
            activityInfo.setCreateBy(user);
            activityInfo.setCreateTime(new Date());
            activityInfo.setTemplateInfoId(templateId);
            activityInfo.setTypeIdentification(activityTemplateInfoService.getActivityType(templateId));
            if (activityInfo.getParticipantNum() == null) {
                activityInfo.setParticipantNum(0);
            }
            activityInfo.setForegroundLink("");
            ActivityInfo returnActivityInfo = activityInfoService.save(activityInfo);
            logger.info("活动创建成功: =>{}", returnActivityInfo);
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "SUCCESS", returnActivityInfo);
        } catch (Exception e) {
            e.printStackTrace();
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动创建异常", null);
            logger.error("活动创建异常,activityTemplateInfo: =>{}", activityInfo);
        }
        return resultInfo;
    }

    /**
     * 修改活动对象
     *
     * @param activityInfo 模板对象
     * @return
     */
    @PostMapping
    @ResponseBody
    @PreAuthorize("hasAnyRole('ROLE_USER_SUPERADMIN','ROLE_USER_ADMIN','ROLE_USER_SELF')")
    public ResultInfo update(ActivityInfo activityInfo,
                             @RequestParam(value = "pcSkipImage", required = false) MultipartFile pcSkipImage,
                             @RequestParam(value = "wapSkipImage", required = false) MultipartFile wapSkipImage) {
        // todo 如果当前用户不存在，返回异常
        ResultInfo resultInfo = null;
        // 如果当前用户与活动用户不匹配，返回异常。
        try {
            // 处理跳转图片
            JSONObject skipImageJson = null;
            if (StringUtils.isNotBlank(activityInfo.getSkipImage())) {
                skipImageJson = JSONObject.parseObject(activityInfo.getSkipImage());
            } else {
                skipImageJson = new JSONObject();
            }
            //图片地址
            String pcImage = null;
            String wapImage = null;
            if (pcSkipImage != null && (!Strings.isNullOrEmpty(pcSkipImage.getOriginalFilename()))) {
                String fileName = pcSkipImage.getOriginalFilename();
                // 验证图片文件格式
                boolean imageFormatFlag = FileUtil.imageFormatVerification(fileName);
                if (!imageFormatFlag) {
                    return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
                            "请选择格式为*.jpg、*.gif、*.bmp、*.png、*.jpeg 的图片", fileName);
                }
                pcImage = uploadFile(pcSkipImage, activityConsoleConfiguration.activitySkipImagePcPath,
                        "skip_image_pc_");
            }
            if (wapSkipImage != null && (!Strings.isNullOrEmpty(wapSkipImage.getOriginalFilename()))) {
                String fileName = wapSkipImage.getOriginalFilename();
                // 验证图片文件格式
                boolean imageFormatFlag = FileUtil.imageFormatVerification(fileName);
                if (!imageFormatFlag) {
                    return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
                            "请选择格式为*.jpg、*.gif、*.bmp、*.png、*.jpeg 的图片", fileName);
                }
                wapImage = uploadFile(wapSkipImage, activityConsoleConfiguration.activitySkipImageWapPath,
                        "skip_image_wap_");
            }
            // 添加跳转图片路径
            if (StringUtils.isNotBlank(activityInfo.getSkipUrl())) {
                if (null != pcImage) {
                    skipImageJson.put("pc", pcImage);
                }
                if (null != wapImage) {
                    skipImageJson.put("wap", wapImage);
                }
                activityInfo.setSkipImage(skipImageJson.toJSONString());
            } else {
                activityInfo.setSkipImage(null);
            }

            ActivityInfo returnActivityInfo = activityInfoService.update(activityInfo);
            logger.info("活动更新成功: =>{}", returnActivityInfo);
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "SUCCESS", returnActivityInfo);
        } catch (Exception e) {
            e.printStackTrace();
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动修改异常", null);
            logger.error("活动修改异常,activityTemplateInfo: =>{}", activityInfo);
        }
        return resultInfo;
    }

    /**
     * 发布活动对象
     *
     * @param id 活动对象Id
     * @return
     */
    @PostMapping("/id/{id}")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ROLE_USER_SUPERADMIN','ROLE_USER_ADMIN','ROLE_USER_SELF')")
    public ResultInfo release(@PathVariable Integer id) {
        // todo 如果当前用户不存在，返回异常
        ResultInfo resultInfo = null;
        Boolean deleteFlag = false;
        String user = getPrincipal().getUsername();
        String authoritiesStr = getPrincipal().getAuthoritiesStr();
        try {
            // 生成前端活动链接
            ActivityInfo activityInfo = getActivityInfo(authoritiesStr, user, id);
            if (activityInfo == null) {
                logger.info("活动发布失败，没有找到活动, id: =>{}", id);
                return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动发布失败，找不到指定活动",
                        null);
            }
            String foregroundLink = foregroundStaticLink + "?activityId=" + id + "&typeIdentification="
                    + activityInfo.getTypeIdentification();
            deleteFlag = activityInfoService.release(foregroundLink, id, user);
            logger.info("发布指定活动：=>{}, id: =>{}", deleteFlag ? "成功" : "失败", id);
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "活动发布成功", foregroundLink);
        } catch (Exception e) {
            logger.info("发布指定活动异常,id：=>{}", id);
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动发布异常", null);
        }
        return resultInfo;
    }

    /**
     * 发布砍价活动对象
     *
     * @param id 活动对象Id
     * @return
     */
    @PostMapping("/barGain/{id}")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ROLE_USER_SUPERADMIN','ROLE_USER_ADMIN','ROLE_USER_SELF')")
    public ResultInfo releaseBargain(@PathVariable Integer id) {
        // todo 如果当前用户不存在，返回异常
        ResultInfo resultInfo = null;
        Boolean deleteFlag = false;
        String user = getPrincipal().getUsername();
        String authoritiesStr = getPrincipal().getAuthoritiesStr();
        try {
            // 生成前端活动链接
            ActivityInfo activityInfo = getActivityInfo(authoritiesStr, user, id);
            if (activityInfo == null) {
                logger.info("活动发布失败，没有找到活动, id: =>{}", id);
                return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动发布失败，找不到指定活动",
                        null);
            }
            if (!activityInfo.getTypeIdentification().equals("bargain")) {
                return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动发布失败，并不是砍价类型的活动",
                        null);
            }
            String foregroundLink = barGainStaticLink + "?activityId=" + id;
            deleteFlag = activityInfoService.release(foregroundLink, id, user);
            logger.info("发布指定活动：=>{}, id: =>{}", deleteFlag ? "成功" : "失败", id);
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "活动发布成功", foregroundLink);
        } catch (Exception e) {
            logger.info("发布指定活动异常,id：=>{}", id);
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动发布异常", null);
        }
        return resultInfo;
    }

    /**
     * 活动上下架(上线或暂停)
     *
     * @param id   活动对象Id
     * @param flag 是否上架
     * @return
     */
    @PostMapping("/id/{id}/run-or-pause")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ROLE_USER_SUPERADMIN','ROLE_USER_ADMIN','ROLE_USER_SELF')")
    public ResultInfo runOrPause(@PathVariable Integer id, Boolean flag) {
        // todo 如果当前用户不存在，返回异常
        ResultInfo resultInfo = null;
        if (flag == null) {
            return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "操作有误，请核实信息。", null);
        }
        Boolean returnFlag = false;
        String user = getPrincipal().getUsername();
        String authoritiesStr = getPrincipal().getAuthoritiesStr();
        try {
            ActivityInfo activityInfo = getActivityInfo(authoritiesStr, user, id);
            if (activityInfo == null) {
                logger.info("指定活动上下架失败，没有找到活动, id: =>{}", id);
                return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动上下架失败，没有找到活动",
                        null);
            }
            if (authoritiesStr.equals("ROLE_USER_SUPERADMIN") || authoritiesStr.equals("ROLE_USER_ADMIN")) {
                returnFlag = activityInfoService.runOrPauseOrSuperUser(flag, id);
            } else {
                returnFlag = activityInfoService.runOrPause(flag, id, user);
            }
            logger.info("指定活动" + (flag ? "上" : "下") + "架，执行完成：=>{}, id: =>{}", returnFlag ? "成功" : "失败", id);
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_OK),
                    "活动" + (flag ? "上" : "下") + "架" + (returnFlag ? "成功" : "失败"), null);
        } catch (Exception e) {
            logger.info("活动上下架异常,id：=>{}", id);
            resultInfo = new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "活动上下架异常", null);
        }
        return resultInfo;
    }

    /**
     * 删除指定活动
     *
     * @param id 活动编号
     * @return
     */
    @DeleteMapping("/id/{id}")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ROLE_USER_SUPERADMIN','ROLE_USER_ADMIN','ROLE_USER_SELF')")
    public Map<String, String> delete(@PathVariable Integer id) {
        // todo 如果当前用户不存在，返回异常
        Boolean deleteFlag = false;
        String user = getPrincipal().getUsername();
        String authoritiesStr = getPrincipal().getAuthoritiesStr();
        try {
            if (authoritiesStr.equals("ROLE_USER_SUPERADMIN") || authoritiesStr.equals("ROLE_USER_ADMIN")) {
                deleteFlag = activityInfoService.deleteSuper(id);
            } else {
                deleteFlag = activityInfoService.delete(id, user);
            }
            logger.info("删除指定活动：=>{}", deleteFlag ? "成功" : "失败");
        } catch (Exception e) {
            logger.info("删除指定活动异常,id：=>{}", id);
        }
        Map<String, String> map = new HashMap<String, String>();
        map.put("deleteFlag", deleteFlag ? "true" : "false");
        return map;
    }

    private String uploadFile(MultipartFile imageFile, String relativePath, String fileNamePrefix) {
        // 根路径
        String realPath = activityConsoleConfiguration.realPath;
        // 绝对路径
        String absolutePath = (realPath + relativePath).replace("/", File.separator);
        String imageFileName = FileUtil.doFile(imageFile, absolutePath, fileNamePrefix);
        // 静态资源映射 + 文件地址 + 上传文件名称
        return relativePath + imageFileName;
    }
}
